/*
 * Copyright (C) 2012-2013 Michael L.R. Marques
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * 
 * Contact: michaellrmarques@gmail.com
 */

package com.jm.commons.components.help.objects;

import com.jm.commons.fio.FileSystem;
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.filechooser.FileFilter;

/**
 * Help File object for use by the Help Control component
 * 
 * @created Nov 30, 2012
 * @author Michael L.R. Marques
 */
public class HelpFile {
    
    /**
     * The system file object
     */
    private File file;
    
    /**
     * The @code{JLabel} for the renderer
     */
    private JLabel label;
    
    /**
     * Help File initialization constructor
     * 
     * @param file 
     */
    public HelpFile(File file) {
        this.file = file;
    }
    
    /**
     * Return the help files system file
     * 
     * @return 
     */
    public File getFile() {
        return this.file;
    }
    
    /**
     * Get the url of the help file
     * 
     * @return
     */
    public URL getURL() {
        try {
            return this.file.toURI().toURL();
        } catch (MalformedURLException murle) {
            System.out.println(murle.getMessage());
        }
        return null;
    }
    
    /**
     * Get the name of the help file
     * 
     * @return 
     */
    public String getName() {
        return this.file.isFile() ? FileSystem.removeExtension(this.file) : this.file.getName();
    }
    
    /**
     * Get the @code{JLabel} renderer
     * 
     * @return 
     */
    public JLabel getRenderer(JComponent component, boolean isSelected) {
        //
        if (this.label == null) {
            this.label = new JLabel(getName());
            this.label.setFont(new Font("Arial", Font.PLAIN, 11));
            this.label.setIcon(new ImageIcon(getClass().getClassLoader().getResource("com/jm/commons/components/help/icons/" + (isDirectory() ? "folder" : "file") + ".png")));
        }
        return this.label;
    }
    
    /**
     * Get the full path of the help file
     * 
     * @return 
     */
    public String getPath() {
        try {
            return this.file.getCanonicalPath();
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
            return this.file.getAbsolutePath();
        }
    }
    
    /**
     * Is the help file a system file
     * 
     * @return 
     */
    public boolean isFile() {
        return this.file.isFile();
    }
    
    /**
     * Is the help file a system directory
     * 
     * @return 
     */
    public boolean isDirectory() {
        return this.file.isDirectory();
    }
    
    /**
     * Does the system file exist
     * 
     * @return 
     */
    public boolean exists() {
        return this.exists();
    }
    
    /**
     * What extensions can the help file use
     * 
     * @return 
     */
    public static String[] getExtensions() {
        return new String[] {"htm", "html", "xhtm", "xhtml"};
    }
    
    /**
     * List all files in the current directory
     * Allow one to include directorys
     * Don't check inside child directorys
     * 
     * @param includeDirectorys
     * @return 
     */
    public List<HelpFile> listFiles(boolean includeDirectorys) {
        return listFiles(false, includeDirectorys);
    }
    
    /**
     * List all files in the current directory
     * Allow one to check inside directorys
     * Allow one to include directorys
     * 
     * @param recursive
     * @param includeDirectorys
     * @return 
     */
    public List<HelpFile> listFiles(boolean recursive, boolean includeDirectorys) {
        // Check if this is a directory
        if (!isDirectory()) {
            return null;
        }
        // Start loading help files
        List<HelpFile> helpFiles = new ArrayList();
        for (File file : FileSystem.listFiles(null, this.file, getExtensions(), recursive, includeDirectorys)) {
            helpFiles.add(new HelpFile(file));
        }
        return helpFiles;
    }
    
    /**
     * List all files in the current directory
     * Allow one to check inside directorys
     * Allow one to include directorys
     * Allow one to user search text
     * Allow one to select if search should be case sensitive
     * Allow one to select if the search text is a regular expression
     * 
     * @param recursive
     * @param search
     * @param caseSensitive
     * @param regex
     * @return 
     */
    public List<HelpFile> listFiles(boolean recursive, boolean includeDirectorys, String search, boolean caseSensitive, boolean regex) {
        // Check if this is a directory
        if (!isDirectory()) {
            return null;
        }
        // Start loading help files
        List<HelpFile> helpFiles = new ArrayList();
        for (File file : FileSystem.listFiles(null, this.file, getExtensions(), recursive, includeDirectorys, search, caseSensitive, regex)) {
            helpFiles.add(new HelpFile(file));
        }
        return helpFiles;
    }
    
    /**
     * Get the file count in the current directory
     * Allow one to include directorys
     * 
     * @param includeDirectorys
     * @return 
     */
    public int fileCount(boolean includeDirectorys) {
        return fileCount(false, includeDirectorys);
    }
    
    /**
     * Get the file count in the current directory
     * Allow one to check inside directorys
     * Allow one to include directorys
     * 
     * @param recursive
     * @param includeDirectorys
     * @return 
     */
    public int fileCount(boolean recursive, boolean includeDirectorys) {
        // Check if this is a diretory
        if (!isDirectory()) {
            return 0;
        }
        // Return the file count
        return FileSystem.listFiles(null, this.file, getExtensions(), recursive, includeDirectorys).size();
    }
    
    /**
     * Get the file count in the current directory
     * Allow one to check inside directorys
     * Allow one to include directorys
     * Allow one to user search text
     * Allow one to select if search should be case sensitive
     * Allow one to select if the search text is a regular expression
     * 
     * @param recursive
     * @param search
     * @param caseSensitive
     * @param regex
     * @return 
     */
    public int fileCount(boolean recursive, boolean includeDirectorys, String search, boolean caseSensitive, boolean regex) {
        // Check if this is a directory
        if (!isDirectory()) {
            return 0;
        }
        // Resturn the file count
        return FileSystem.listFiles(null, this.file, getExtensions(), recursive, includeDirectorys, search, caseSensitive, regex).size();
    }
    
    /**
     * Get the file filter with extensions associated with help file types
     * 
     * @return 
     */
    public FileFilter getFileFilter() {
        return new FileFilter() {
            @Override public boolean accept(File f) {
                return FileSystem.isValidExtension(file, getExtensions());
            }
            @Override public String getDescription() {
                return "Web Files (*.htm, *.html, *.xhtm, *.xhtml)";
            }
        };
    }

}
